home *** CD-ROM | disk | FTP | other *** search
/ DS-CD ROM 2 1993 August / DS CD-ROM 2.Ausgabe (August 1993).iso / programm / ds0257 / demo.exe / QUEUES.DEM < prev    next >
Text File  |  1992-02-16  |  27KB  |  841 lines

  1. ; ----------------------------
  2. ; QUEUES.DEM   - Demoprogramm für die Routinen aus QUEUES.BIB
  3. ;                (und implizit: MQUEUE.LIB, SQUEUE.LIB und MEMORY.LIB)
  4. ;                (für den A86)
  5. ;
  6. ;                (c) Bernd Schemmer 1992
  7. ;                Letzter Update: 15.02.1992
  8. ;
  9. ; Übersetzen:
  10. ;  A86 MQUEUE.DEM DEMOS.INC TO MQUEUE.COM
  11. ;
  12. ; Hinweis: Die Environment-Variable 'A86' muß den Dateinamen 'MACROS.MAC'
  13. ;          enthalten und die .LIB-Dateien müssen über die Datei A86.LIB
  14. ;          erreichbar sein.
  15. ;
  16. ; ---------------------------
  17.  
  18.          jmp start
  19.  
  20. ; ----------------------------
  21.                               ; Meldungen und Fehlermeldungen
  22. logo  db CR,LF
  23.       db 'QUEUES.DEM  - Demoprogramm für die Routinen aus QUEUES.BIB' ,CR,LF
  24.       db '----------------------------------------------------------',CR,LF
  25.       db 'Das Programm führt folgende Arbeitsschritte durch:        ',CR,LF
  26.       db '1. Lesen der Eingabe-Datei                                ',CR,LF
  27.       db '2. Einrichten von 2 meldungsorientierten Queuen und       ',CR,LF
  28.       db '   1 streamorientierten Queue                             ',CR,LF
  29.       db '3. Verteilen der Zeilen der Eingabe-Datei auf die 3 Queuen',CR,lF
  30.       db '   nach folgenden Algorithmus:                            ',CR,LF
  31.       db '   Alle Zeilen, die mit einem Semikolon beginnen kommen   ',CR,LF
  32.       db '   in die erste Queue, alle weiteren Zeilen, die ein Semi-',CR,LF
  33.       db '   kolon enthalten kommen in die zweite Queue und alle    ',CR,LF
  34.       db '   restlichen Zeilen kommen in die dritte Queue.          ',CR,LF
  35.       db '4. Schreiben der 3 Queuen in die Ausgabe-Datei            ',CR,LF
  36.       db CR,LF
  37.       db 'Das Demo muß folgendermaßen aufgerufen werden:'           ,CR,LF
  38.       db '      QUEUES.COM eingabedatei ausgabedatei'               ,CR,LF
  39.       db CR,LF,CR,LF
  40.       db 'Bitte eine Taste drücken (ESC = Programm-Abbruch) ...'    ,CR,LF
  41.       db CR,LF
  42. GETLENGTH logo
  43.                               ; Meldungen
  44. MakeMsg ReadMsg,    '--- Lese die Eingabe-Datei ...'
  45. MakeMsg Open1Msg,   '--- Öffne die 1. Queue ...'
  46. MakeMsg Open2Msg,   '--- Öffne die 2. Queue ...'
  47. MakeMsg Open3Msg,   '--- Öffne die 3. Queue ...'
  48. MakeMsg ProceedMsg, '--- Verteile die Zeilen auf die Queuen ...'
  49. MakeMsg Write1Msg,  '--- Schreibe die 1. Queue in die Ausgabe-Datei ...'
  50. MakeMsg Write2Msg,  '--- Schreibe die 2. Queue in die Ausgabe-Datei ...'
  51. MakeMsg Write3Msg,  '--- Schreibe die 3. Queue in die Ausgabe-Datei ...'
  52. MakeMsg Close1Msg,  '--- Schliesse die Queue 1 ...'
  53. MakeMsg Close2Msg,  '--- Schliesse die Queue 2 ...'
  54. MakeMsg Close3Msg,  '--- Schliesse die Queue 3 ...'
  55.  
  56.                               ; Fehlermeldungen
  57. MakeMsg ParamError,     '*** Fehlerhaften Parameter oder zuwenig Parameter angegeben.'
  58. MakeMsg MemoryError,    '*** Zuwenig freier Speicher.'
  59. MakeMsg OFileError,     '*** Fehler beim Öffnen der Ausgabe-Datei'
  60. MakeMsg IFileError,     '*** Fehler beim Lesen der Eingabe-Datei'
  61. MakeMsg IFileError1,    '*** Eingabe-Datei ist zu groß'
  62. MakeMsg WriteFileError, '*** Fehler beim Schreiben der Ausgabe-Datei.'
  63. MakeMsg ReadFileError,  '*** Fehler beim Lesen der Datei.'
  64. MakeMsg OutputError,    '*** Fehler beim Schreiben in die Ausgabe-Datei.'
  65.  
  66.  
  67. OutputFileHandle   dw 0       ; Handle der Ausgabe-Datei
  68. InputFileHandle    dw 0       ; Handle der Eingabe-Datei
  69. InputFileLength    dw 0       ; Größe der Eingabe-Datei
  70.  
  71. InputFileOff       dw 0       ; Pufferzeiger für die Eingabe-Datei
  72. InputFileSeg       dw 0       ; Segment des Speicherblocks zum Lesen der
  73.                               ; Eingabe-Datei
  74.  
  75. Queue1Handle       dw 0       ; Handles für die Queuen
  76. Queue2Handle       dw 0
  77. Queue3Handle       dw 0
  78.  
  79.                               ; Puffer für die Zeilen
  80. LineBuffer         db 0,257 dup 20h
  81.  
  82. MaxQueueHandles    EQU 05h    ; das Demo benötigt max. 3 Queuen
  83.  
  84. ; ----------------------------
  85. start:
  86.          call ShowLogoAndAsk  ; Logo ausgeben, Speicherblock verkleinern
  87.                               ; und Taste lesen
  88. ; ----------------------------
  89. l2:
  90.          Write_String ReadMsg
  91.  
  92.                               ; Ein- und Ausgabe-Dateien eröffnen
  93.          call OpenInAndOutputFiles
  94.          IF c jmp ErrorEnde1  ; Fehler!
  95.  
  96. ; ----------------------------
  97.                               ; Größe für die 3 Queuen berechnen
  98.          mov bx,0FFFFh
  99.          call GetMemoryBlock
  100.          cmp ax,08
  101.          je >l1
  102.          stc
  103.          call CheckQueueError
  104.          if c jmp ErrorEnde1
  105. l1:
  106.          mov ax,bx            ; AX = freier Speicher in Paragraphen
  107.          mov cx,0FFFFh        ; CX = 1 Segment in Byte
  108.          cmp ax,3000h
  109.          jae >l1              ; 1 Segment pro Queue ist möglich
  110.          shl ax,1
  111.          shl ax,1             ; AX = (freier Speicher in Byte) / 4
  112.          mov cx,ax            ; CX = Größe für eine Queue in Byte
  113. l1:
  114.  
  115. ; ----------------------------
  116.          push cx
  117.          Write_String Open1Msg
  118.                               ; Öffnen der ersten Queue (meldungsorientiert)
  119.          mov ax,01h
  120.          call OpenQueue
  121.          call CheckQueueError
  122.          if c jmp ErrorEnde1
  123.          mov Queue1Handle,bx  ; Handle der Queue sichern
  124.          pop cx
  125. ; ----------------------------
  126.          push cx
  127.          Write_String Open2Msg
  128.                               ; Öffnen der zweiten Queue (meldungsorientiert)
  129.          mov ax,01h
  130.          call OpenQueue
  131.          call CheckQueueError
  132.          if c jmp ErrorEnde1
  133.          mov Queue2Handle,bx  ; Handle der Queue sichern
  134.          pop cx
  135.  
  136. ; ----------------------------
  137.          Write_String Open3Msg
  138.                               ; Öffnen der dritten Queue (streamorientiert)
  139.          mov ax,0h
  140.          call OpenQueue
  141.          call CheckQueueError
  142.          if c jmp ErrorEnde1
  143.          mov Queue3Handle,bx  ; Handle der Queue sichern
  144.  
  145. ; ----------------------------
  146.  
  147.          call ShowQueueData
  148.          if c jmp ErrorEnde1
  149.  
  150. ; ----------------------------
  151.          Write_string ProceedMsg
  152.  
  153.          mov B PunktZaehler,0
  154.  
  155. ReadLineLoop:
  156.          call LaufzeitAnzeige
  157.  
  158.          call GetNextLine     ; Zeile lesen
  159.          jc ReadLineLoopEnd   ; EOF erreicht
  160.  
  161.          mov cl,LineBuffer
  162.          xor ch,ch            ; CX = Länge der Zeile
  163.          lea si,LineBuffer+1  ; DS:SI -> Zeile
  164.          jcxz WriteQueue3     ; leere Zeilen kommen in die Queue3
  165.  
  166.          mov al,';'
  167.          cmp b[si],al
  168.          je WriteQueue1       ; Zeilen, die mit ';' beginnen kommen in
  169.                               ; die Queue1
  170.          mov es,cs
  171.          mov di,si
  172.          push cx
  173.          repne scasb
  174.          pop cx
  175.          je WriteQueue2       ; Zeilen, die nicht mit einem ';' beginnen,
  176.                               ; aber ein ';' enthalten kommen in
  177.                               ; die Queue2
  178.  
  179.                               ; und alle anderen Zeilen kommen in Queue3
  180. WriteQueue3:
  181.          mov bx,Queue3Handle
  182.                               ; CR und LF an die Zeile anhängen (falls möglich)
  183.          cmp cx,255           ; CX = Zeilenlänge
  184.          je >l1               ; nicht möglich
  185.          push bx
  186.          mov bx,cx
  187.          mov w[si+bx],LF by CR
  188.          pop bx
  189.          inc cx,2             ; und Zeilenlänge erhöhen
  190.          jmp >l1
  191.  
  192. WriteQueue2:
  193.          mov bx,Queue2Handle
  194.          jmp >l1
  195.  
  196. WriteQueue1:
  197.          mov bx,Queue1Handle
  198. l1:
  199.                               ; DS:SI -> Meldung oder Byte für die Queue
  200.                               ; CX = Länge der Meldung oder Anzahl der Bytes
  201.                               ; BX = Handle der Queue
  202.          call WriteQueue      ; WriteQueue entscheidet selbst, ob es sich
  203.                               ; um eine meldungs- oder streamorientierte
  204.                               ; Queue handelt.
  205.          call CheckQueueError
  206.          jnc ReadLineLoop
  207.          jmp ErrorEnde1
  208.  
  209. ; ------------------
  210. ReadLineLoopEnd:
  211.  
  212.          mov B PunktZaehler,0
  213.                               ; Dateiende erreicht
  214.          call ShowCR_LF
  215.  
  216.          call ShowQueueData
  217.          if c jmp ErrorEnde1
  218.  
  219. ; ----------------------------
  220.                               ; 1. Queue ausgeben
  221.          Write_String Write1Msg
  222.  
  223. l00:
  224.          mov bx,Queue1Handle
  225.          mov cx,255
  226.          mov si,offset LineBuffer+1
  227.          call ReadQueue
  228.          call CheckQueueError
  229.          jnc >l1
  230.          call OutputMsg
  231.          call ShowCR_LF
  232.          jmp >l2              ; nächste Queue
  233.  
  234. l1:
  235.                               ; Zeile schreiben
  236.          mov bx,OutputFileHandle
  237.          mov dx,offset LineBuffer+1
  238.          mov ah,040h
  239.          int 021h
  240.          call CheckQueueError
  241.          if c jmp ErrorEnde1
  242.  
  243.          mov dx,offset CR_LF  ; CR_LF anhängen
  244.          mov cx,CR_LF_Length
  245.          mov ah,040h
  246.          int 021h
  247.          call CheckQueueError
  248.          jnc l00
  249.          jmp ErrorEnde1
  250.  
  251. ; ----------------------------
  252. l2:
  253.          Write_String Write2Msg
  254.                               ; 2. Queue ausgeben
  255. l00:
  256.          mov bx,Queue2Handle
  257.          mov cx,255
  258.          mov si,offset LineBuffer+1
  259.          call ReadQueue
  260.          call CheckQueueError
  261.          jnc >l1
  262.          call OutputMsg
  263.          call ShowCR_LF
  264.          jmp >l2              ; nächste Queue
  265. l1:
  266.                               ; Zeile schreiben
  267.          mov bx,OutputFileHandle
  268.          mov dx,offset LineBuffer+1
  269.          mov ah,040h
  270.          int 021h
  271.          call CheckQueueError
  272.          if c jmp ErrorEnde1
  273.  
  274.          mov dx,offset CR_LF  ; CR_LF anhängen
  275.          mov cx,CR_LF_Length
  276.          mov ah,040h
  277.          int 021h
  278.          call CheckQueueError
  279.          jnc l00
  280.          jmp ErrorEnde1
  281.  
  282. ; ----------------------------
  283. l2:
  284.          Write_String Write3Msg
  285.                               ; 3. Queue ausgeben
  286. l00:
  287.          mov bx,Queue3Handle
  288.          mov cx,200
  289.          mov si,offset LineBuffer+1
  290.          call ReadQueue
  291.          call CheckQueueError
  292.          jnc >l1
  293.          call OutputMsg
  294.          call ShowCR_LF
  295.          jmp >l2              ; nächste Queue
  296. l1:
  297.                               ; Bytes schreiben
  298.          mov bx,OutputFileHandle
  299.          mov dx,offset LineBuffer+1
  300.          mov ah,040h
  301.          int 021h
  302.          call CheckQueueError
  303.          jnc l00
  304.          jmp ErrorEnde1
  305.  
  306. ; ----------------------------
  307. l2:
  308.          call ShowQueueData
  309.          if c jmp ErrorEnde1
  310.  
  311.                               ; Schliesse die Queuen
  312.          Write_String Close1Msg
  313.  
  314.          mov bx,Queue1Handle
  315.          call CloseQueue
  316.          call CheckQueueError
  317.          jc ErrorEnde1
  318.  
  319.          Write_String Close2Msg
  320.  
  321.          mov bx,Queue2Handle
  322.          call CloseQueue
  323.          call CheckQueueError
  324.          jc ErrorEnde1
  325.  
  326.          Write_String Close3Msg
  327.  
  328.          mov bx,Queue3Handle
  329.          call CloseQueue
  330.          call CheckQueueError
  331.          jc ErrorEnde1
  332.  
  333.          call GetMaxQueues
  334.          call CheckQueueError
  335.          jc ErrorEnde1
  336.  
  337.          call ShowQueueStatistik
  338.  
  339.          jmp SHORT Ende
  340. ; ------------------
  341.  
  342. ErrorEnde1:
  343.          push cx,dx
  344.          call ShowCR_LF
  345.          pop dx,cx
  346.                               ; Fehlerausgang
  347.                               ; DX = Offset der Meldung
  348.                               ; CX = Länge der Meldung
  349.          call OutputMsg
  350.          call ShowCR_LF
  351.  
  352. ErrorEnde:
  353.          mov al,0FFh
  354. Ende:
  355.                               ; Ein- und Ausgabedateien schliessen
  356.          call CloseFiles
  357.  
  358.          EndProcess
  359.  
  360.  
  361. ; ----------------------------
  362. ; ShowQueueData
  363. ;
  364. ; Funktion: Ausgabe der Daten aller Queuen und der globalen Daten
  365. ;
  366. ShowQueueData:
  367.          mov bx,Queue1Handle
  368.          call GetQueueData    ; Daten der Queue ausgeben
  369.          call CheckQueueError
  370.          jc ret
  371.          call ShowMHeader     ; 1. Queue ist meldungsorientiert
  372.  
  373.          mov bx,Queue2Handle
  374.          call GetQueueData    ; Daten der Queue ausgeben
  375.          call CheckQueueError
  376.          jc ret
  377.          call ShowMHeader     ; 2. Queue ist meldungsorientiert
  378.  
  379.          mov bx,Queue3Handle
  380.          call GetQueueData    ; Daten der Queue ausgeben
  381.          call CheckQueueError
  382.          jc ret
  383.          call ShowSHeader     ; 1. Queue ist streamorientiert
  384.  
  385.          call GetMaxQueues    ; und die globalen Daten ausgeben
  386.          call CheckQueueError
  387.          jc ret
  388.          call ShowQueueStatistik
  389.          clc
  390.          ret
  391.  
  392. ; ----------------------------
  393. ; ShowQueueStatistik
  394. ;
  395. ; Funktion: Ausgabe der globalen Werte
  396. ;
  397. ; Eingabe:  Register wie von der Routine GetMaxQueues geliefert
  398. ;
  399. QueuesStatMsg db CR,LF
  400.          db 'Daten der Queue-Verwaltung: '
  401.          db CR,LF
  402.          db 'Anzahl möglicher Queuen:  '
  403. m1       db '_____,'
  404.          db CR,LF
  405.          db 'Anzahl geöffneter Queuen: '
  406. m2       db '_____'
  407.          db CR,LF
  408.          db 'davon streamorientiert:   '
  409. m3       db '___,   '
  410.          db 'und meldungsorientiert:   '
  411. m4       db '___'
  412.          db CR,LF
  413. GETLENGTH QueuesStatMsg
  414.  
  415. ShowQueueStatistik:
  416.          push es
  417.          mov es,cs
  418.  
  419.          push ax
  420.          mov di,offset m4
  421.          call Konvert_AL_To_Dezstring
  422.          pop ax
  423.  
  424.          mov al,ah
  425.          mov di,offset m3
  426.          call Konvert_AL_To_Dezstring
  427.  
  428.          mov ax,cx
  429.          mov di,offset m2
  430.          call Konvert_AX_To_Dezstring
  431.  
  432.          mov ax,dx
  433.          mov di,offset m1
  434.          call Konvert_AX_To_Dezstring
  435.  
  436.          write_string QueuesStatMsg
  437.  
  438.          pop es
  439.          ret
  440.  
  441. ; ----------------------------
  442. ; ShowMHeader
  443. ;
  444. ; Funktion: Ausgabe der globalen Daten einer meldungsorientierten Queue
  445. ;
  446. ; Eingabe:  AX, DX, CX und DI wie von der Routine GetQueueData geliefert
  447. ;
  448. MHeaderMsg db CR,LF
  449.            db 'Daten der meldungs-orientierten Queue bei '
  450. m3         db '____h: '
  451.            db CR,LF
  452.            db 'Gesamtspeicher: '
  453. m4         db '_____, freier Speicher: '
  454. m5         db '_____, '
  455. m6         db '_____ Meldungen in der Queue'
  456.            db CR,LF
  457. GETLENGTH MHeaderMsg
  458.  
  459. ShowMHeader:
  460.          push es
  461.          mov es,cs
  462.  
  463.          push ax
  464.          mov ax,di
  465.          mov di,offset m3
  466.          call Konvert_AX_To_Hexstring
  467.          pop ax
  468.  
  469.          mov di,offset m6
  470.          call Konvert_AX_To_Dezstring
  471.  
  472.          mov di,offset m4
  473.          mov ax,dx
  474.          call Konvert_AX_To_Dezstring
  475.  
  476.          mov di,offset m5
  477.          mov ax,cx
  478.          call Konvert_AX_To_Dezstring
  479.  
  480.          Write_String MHeaderMsg
  481.  
  482.          pop es
  483.          ret
  484.  
  485. ; ----------------------------
  486. ; ShowSHeader
  487. ;
  488. ; Funktion: Ausgabe der globalen Daten einer streamorientierten Queue
  489. ;
  490. ; Eingabe:  AX, DX, CX und DI wie von der Routine GetQueueData geliefert
  491. ;
  492. SHeaderMsg db CR,LF
  493.            db 'Daten der stream-orientierten Queue bei '
  494. m3         db '____h: '
  495.            db CR,LF
  496.            db 'Gesamtspeicher: '
  497. m4         db '_____, freier Speicher: '
  498. m5         db '_____, '
  499.            db 'belegter Speicher: '
  500. m6         db '_____',CR,LF
  501. GETLENGTH SHeaderMsg
  502.  
  503. ShowSHeader:
  504.          push es
  505.          mov es,cs
  506.  
  507.          push ax
  508.          mov ax,di
  509.          mov di,offset m3
  510.          call Konvert_AX_To_Hexstring
  511.          pop ax
  512.  
  513.          mov di,offset m6
  514.          call Konvert_AX_To_Dezstring
  515.  
  516.          mov di,offset m4
  517.          mov ax,dx
  518.          call Konvert_AX_To_Dezstring
  519.  
  520.          mov di,offset m5
  521.          mov ax,cx
  522.          call Konvert_AX_To_Dezstring
  523.  
  524.          Write_String SHeaderMsg
  525.  
  526.          pop es
  527.          ret
  528.  
  529. ; ----------------------------
  530. ; CheckQueueError
  531. ;
  532. ; Funktion: Ermitteln der zu einer Fehlernummer der Routinen für die
  533. ;           Verwaltung der Queuen gehörenden Fehlermeldung
  534. ;
  535. ; Eingabe:  AX = Fehlercode der Routine
  536. ;           CF = CF der Routine
  537. ;
  538. ; Ausgabe:  CF = 0 ->> kein Fehler
  539. ;                      kein Register verändert
  540. ;           CF = 1 ->> Fehler
  541. ;                      DX = Offset der Fehlermeldung
  542. ;                      CX = Länge der Fehlermeldung
  543. ;                      AX unverändert
  544. ;
  545.                               ; Fehlermeldungen der Routine aus
  546.                               ; MQUEUE.LIB
  547. QueueErrorMsg1  db '*MQ* Keine weitere Meldung in der Queue!'
  548. QueueErrorMsg2  db '*MQ* Nicht mehr genügend freier Speicher in der Queue!'
  549. QueueErrorMsg3  db '*MQ* Falsche Größe für die Queue angegeben!'
  550. QueueErrorMsg4  db '*MQ* Puffer ist für die nächste Meldung zu klein!'
  551. QueueErrorMsg5  db '*MQ* Angegebene Meldung ist zu lang!'
  552. QueueErrorMsg6  db '*MQ* Gleichzeitiger Zugriff von mehreren Routinen nicht erlaubt!'
  553.  
  554.                               ; Fehlermeldungen der Routine aus
  555.                               ; SQUEUE.LIB
  556. QueueErrorMsg7  db '*SQ* Kein weiteres Byte in der Queue!'
  557. QueueErrorMsg8  db '*SQ* Nicht mehr genügend freier Speicher in der Queue!'
  558. QueueErrorMsg9  db '*SQ* Falsche Größe für die Queue angegeben'
  559. QueueErrorMsg10 db '*SQ* Gleichzeitiger Zugriff von mehreren Routinen nicht erlaubt!'
  560.  
  561.                               ; Fehlermeldungen der Routine aus
  562.                               ; MEMORY.LIB
  563. QueueErrorMsg11 db '*ME* Falsche Adresse angegeben!'
  564. QueueErrorMsg12 db '*ME* Falsche Blockgröße angegeben!'
  565. QueueErrorMsg13 db '*ME* Speicherblock ist frei!'
  566. QueueErrorMsg14 db '*ME* Speicherblock gehört DOS!'
  567. QueueErrorMsg15 db '*ME* Block ist kein Hauptblock!'
  568. QueueErrorMsg16 db '*ME* Falscher Name für den Block angegeben!'
  569. QueueErrorMsg17 db '*ME* Block nicht gefunden!'
  570.  
  571.                               ; Fehlermeldungen der Routine aus
  572.                               ; QUEUES.LIB
  573. QueueErrorMsg18 db '*QS* Funktion wird von der Queue nicht unterstützt!'
  574. QueueErrorMsg19 db '*QS* Falsches Handle angegeben!'
  575. QueueErrorMsg20 db '*QS* kein freies Handle mehr vorhanden!'
  576.  
  577.                               ; DOS-Fehlermdeldungen
  578. QueueErrorMsg21 db 'DOS: Fehlercode 07'
  579. QueueErrorMsg22 db 'DOS: Fehlercode 08'
  580. QueueErrorMsg23 db 'DOS: Fehlercode 09'
  581.  
  582. QueueErrorMsgU  db '*** Unbekannter Fehlercode: '
  583. UErrorCode      db                             '____h!'
  584. QueueErrorMsgL  db 0       ; Dummy-Eintrag
  585.  
  586.                      ; Tabelle der Fehlernummern und Fehlermeldungen
  587.                      ;
  588.                      ; Fehlernummer          Offset der Fehlermeldung
  589.                      ; -----------------------------------------------
  590.     QueueErrorTable dw MQueueIsEmpty       , Offset  QueueErrorMsg1
  591.                     dw MQueueIsFull        , Offset  QueueErrorMsg2
  592.                     dw MQueueLengthError   , Offset  QueueErrorMsg3
  593.                     dw MQueueBufferError   , Offset  QueueErrorMsg4
  594.                     dw MQueueMessageError  , Offset  QueueErrorMsg5
  595.                     dw MQueueAktivError    , Offset  QueueErrorMsg6
  596.  
  597.                     dw SQueueIsEmpty       , Offset  QueueErrorMsg7
  598.                     dw SQueueIsFull        , Offset  QueueErrorMsg8
  599.                     dw SQueueLengthError   , Offset  QueueErrorMsg9
  600.                     dw SQueueAKtivError    , Offset  QueueErrorMsg10
  601.  
  602.                     dw MemoryBlockError    , Offset  QueueErrorMsg11
  603.                     dw InvalidBlockLength  , Offset  QueueErrorMsg12
  604.                     dw BlockIsFree         , Offset  QueueErrorMsg13
  605.                     dw BlockBelongsToDOS   , Offset  QueueErrorMsg14
  606.                     dw BlockIsNoMainBlock  , Offset  QueueErrorMsg15
  607.                     dw InvalidBlockName    , Offset  QueueErrorMsg16
  608.                     dw BlockNotFound       , Offset  QueueErrorMsg17
  609.  
  610.                     dw UnknownQSubFunction , Offset  QueueErrorMsg18
  611.                     dw InvalidQUeueHandle  , Offset  QueueErrorMsg19
  612.                     dw NoMoreQueueHandles  , Offset  QueueErrorMsg20
  613.  
  614.                     dw 007                 , Offset  QueueErrorMsg21
  615.                     dw 008                 , Offset  QueueErrorMsg22
  616.                     dw 009                 , Offset  QueueErrorMsg23
  617.  
  618.                               ; Eintrag für unbekannte Fehlercodes
  619.     QueueUnknownErr dw 0                   , Offset  QueueErrorMsgU
  620.  
  621.                               ; Eintrag für die Ermittlung der Länge
  622.                               ; der letzten Fehlermeldung
  623.                     dw 0                   , Offset  QueueErrorMsgL
  624.  
  625. CheckQueueError:
  626.          jnc ret              ; CF = 0 ->> kein Fehler aufgetreten
  627.  
  628.          push si,ds,ax        ; CF = 1 ->> Fehler aufgetreten,
  629.                               ;            Offset der Fehlermeldung ermitteln
  630.          mov ds,cs            ; DS = CS
  631.          mov si,offset QueueErrorTable
  632.                               ; DS:SI -> Fehlertabelle
  633.  
  634.                               ; Eintrag für unbekannte Fehlercodes korrigieren
  635.          mov QueueUnknownErr,ax
  636.  
  637.          push es,di,ax
  638.          mov es,cs
  639.          mov di,offset UErrorCode
  640.          call Konvert_AX_To_HexString
  641.          pop ax,di,es
  642.          mov dx,ax            ; Fehlernummer nach DX
  643. l0:
  644.          lodsw
  645.          cmp ax,dx
  646.          lodsw
  647.          jne l0
  648.  
  649.          mov dx,ax            ; DX = Offset der Fehlermeldung
  650.          mov cx,[si+2]        ; CX = Offset der nächsten Fehlermeldung
  651.          sub cx,dx            ; CX = Länge der Fehlermeldung
  652.          stc
  653.          pop ax,ds,si
  654.          ret
  655.  
  656. ; ----------------------------
  657. ; OpenInAndOutputFiles
  658. ;
  659. ; Funktion: Öffnet die Ein- und Ausgabe-Dateien und liest die Eingabe-Datei
  660. ;
  661. ; Ausgabe:  CF = 0 ->> okay
  662. ;           CF = 1 ->> Fehler
  663. ;                      DX = Offset der Fehlermeldung
  664. ;                      CX = Länge der Fehlermeldung
  665. ;
  666. OpenInAndOutputFiles:
  667.          mov bx,1000h         ; Speicher zum Lesen der Eingabe-Datei anfordern
  668.          mov ah,048h          ; 1 Segment
  669.          int 021h
  670.          jnc >l1
  671.                               ; Fehler, nicht genügend Speicher vorhanden
  672.          mov dx,offset MemoryError
  673.          mov cx,MemoryError_LENGTH
  674.          stc
  675.          ret
  676.  
  677. ; ------------------
  678. l1:
  679.          mov InputFileSeg,ax  ; Segment sichern
  680.  
  681.          mov si,080h          ; Parameter bearbeiten
  682.          lodsb
  683.          or al,al
  684.          jnz >l1
  685.                               ; Fehler: Keine Parameter angegeben
  686. ParameterError:
  687.          mov dx,offset ParamError
  688.          mov cx,ParamError_LENGTH
  689.          stc
  690.          ret
  691.  
  692. ; ------------------
  693. l1:
  694.          call GetFileName     ; Anfang des ersten Dateinamens suchen
  695.          jc ParameterError
  696.                               ; DS:DX -> erster Dateiname als ASCIIZ-String
  697. ; ------------------
  698.          mov ax,03D02h        ; Eingabe-Datei öffnen
  699.          int 021h
  700.          jnc >l1
  701. ; ------------------
  702. InputFileError:
  703.          mov dx,offset IFileError
  704.          mov cx,IFileError_LENGTH
  705.          stc
  706.          ret
  707. ; ------------------
  708. l1:
  709.          mov InputFileHandle,ax         ; Handle der Eingabe-Datei sichern
  710. ; ------------------
  711.          call GetFileName     ; Name der Ausgabe-Datei ermitteln
  712.          jc ParameterError
  713. ; ------------------
  714.                               ; Ausgabe-Datei anlegen
  715.          mov cx,0             ; CX = Standard-Attribte
  716.          mov ah,03Ch          ; Datei erstellen
  717.          int 021h
  718.          jnc >l1
  719. ; ------------------
  720. OutputFileError:
  721.          mov dx,offset OFileError
  722.          mov cx,OFileError_LENGTH
  723.          stc
  724.          ret
  725. ; ------------------
  726. l1:
  727.          mov OutputFileHandle,ax        ; Handle der Ausgabe-Datei sichern
  728. ; ------------------
  729.          mov ah,03Fh          ; und Eingabe-Datei lesen
  730.          mov cx,0FFF5h
  731.          mov bx,InputFileHandle
  732.          lds dx,InputFileOff  ; DS <> CS
  733.          int 021h
  734.          mov ds,cs            ; DS = CS
  735.          jc InputFileError
  736.          cmp ax,cx
  737.          jb >l1
  738. ; ------------------
  739. InputFileError1:
  740.          mov dx,offset IFileError1
  741.          mov cx,IFileError1_LENGTH
  742.          stc
  743.          ret
  744. ; ------------------
  745. l1:
  746.          mov InputFileLength,ax         ; Länge der Datei sichern
  747.          clc
  748.          ret
  749.  
  750. ; ----------------------------
  751. ; GetFileName
  752. ;
  753. ; Funktion: Ermittelt den nächsten Parameter und konvertiert ihn in
  754. ;           einen ASCIIZ-String
  755. ;
  756. ; Eingabe:  SI -> Ende des letzte Parameters
  757. ;
  758. ; Ausgabe:  CF = 0 ->> okay, DX -> Anfang des Parameters
  759. ;           CF = 1 ->> Fehler
  760. ;
  761. GetFileName:
  762. l0:                           ; Anfang des Parameters suchen
  763.          lodsb
  764.          cmp al,BLANK
  765.          je l0
  766.          cmp al,TAB
  767.          je l0
  768.          cmp al,CR
  769.          je >l8
  770. ; ------------------
  771.          lea dx,[si-1]        ; Anfang des Parameters gefunden
  772.  
  773. l1:                           ; Ende des Parameters suchen
  774.          lodsb
  775.          cmp al,BLANK
  776.          je >l2
  777.          cmp al,TAB
  778.          je >l2
  779.          cmp al,CR
  780.          je >l2
  781.          jmp l1
  782. l2:
  783.          mov b[si-1],0        ; Nullbyte eintragen
  784.          clc
  785.          ret
  786.  
  787. ; ------------------
  788. l8:
  789.          stc
  790.          ret
  791.  
  792. ; ----------------------------
  793. ; GetNextLine
  794. ;
  795. ; Funktion: Ermittelt die nächste Zeile der Eingabe-Datei aus dem Puffer
  796. ;
  797. ; Eingabe:  DS = CS
  798. ;
  799. ; Ausgabe:  CF = 0 ->> LineBuffer ist gefüllt
  800. ;           CF = 1 ->> EOF erreicht
  801. ;
  802. GetNextLine:
  803.          mov ax,InputFileOff
  804.          cmp ax,InputFileLength
  805.          jb >l1
  806.          stc                  ; EOF erreicht
  807.          ret
  808. l1:
  809.          push ds,es,si,di,cx
  810.  
  811.          mov es,cs            ; ES = CS
  812.          mov di,offset LineBuffer
  813.                                         ; ES:DI -> Längenzähler des Zeilenpuffers
  814.          xor cx,cx                      ; CX = Längenzähler
  815.          lds si,cs:InputFileOff         ; DS:SI -> akt. Position im Puffer
  816.  
  817.          push di
  818.          inc di               ; ES:DI -> Zeilenpuffer
  819. l0:
  820.          cmp cl,255xD         ; max. Zeilenlänge erreicht?
  821.          je >l1               ; ja
  822.  
  823.          lodsb
  824.          cmp al,CR
  825.          je >l1               ; Zeilenende erreicht
  826.          stosb                ; Zeichen übernehmen
  827.          inc cx               ; Zähler korrigieren
  828.          jmp l0
  829. l1:
  830.          cmp b[si],LF
  831.          if e inc si          ; LF am Zeilenende überlesen
  832.          pop di
  833.          mov es:[di],cl       ; Länge der Zeile eintragen
  834.  
  835.          mov cs:InputFileOff,si         ; und Pufferzeiger sichern
  836. l9:
  837.          clc
  838.          pop cx,di,si,es,ds
  839.          ret
  840.  
  841.